package com.demo.utils;

import java.sql.Connection;
import java.sql.SQLException;

//工具类---事务管理器
public class TransactionMnanager {
    private TransactionMnanager(){}

   /* private static Connection conn;

    static {
        try {
            conn = C3P0Utiles.getConnection();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }*/

    /**
     * 扩展:通过ThreadLocal，保证每个线程各自使用各自的Conn对象
     * 当在多线程环境下时，所有线程都用统一个conn必然会出现线程安全问题。
     * 此时可以通过ThreadLocal让每个Thread都具有自己的Conn，保证线程安全。
     */
    //可以直接把当前线程对象当作键
    private static final ThreadLocal<Connection> tl=new ThreadLocal<Connection>(){
        //给定匿名内部类来继承ThreadLocal去重写initialValue()这个方法来给定初始值
        @Override
        protected Connection initialValue() {
            try {
                //给定的初始值就是数据库连接对象
                return C3P0Utiles.getConnection();
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
    };

    /*
    * 开启事务
    * */
    public static void startTran(){
        try {
            //conn.setAutoCommit(false);
            tl.get().setAutoCommit(false);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /*

    提交事务*/
    public static void commitTran(){
        try {
            //conn.commit();
            tl.get().commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }


    /*
    * 回滚事务
    *
    * */
    public static void rollbackTran(){
        try {
            //conn.rollback();
            tl.get().rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /*
    *
    * 获取连接
    * */
    public static Connection getConn(){
        //return conn;
        return tl.get();
    }


    /*
    * 释放资源
    *
    * */
    public static void release(){
        //C3P0Utiles.close(conn,null,null);
        C3P0Utiles.close(tl.get(),null,null);
        tl.remove();
    }
}

